﻿// -----------------------------------------------------------------------
// <copyright file="CommandLineApplication.cs" company="FCIS">
// You are welcome to do whatever you want with the code in this file
// </copyright>
// -----------------------------------------------------------------------

namespace ImagePackage.CommandLine
{
    using System;
    using System.Collections.Generic;
    using Utilities;

    /// <summary>
    /// The command line application
    /// </summary>
    public static class CommandLineApplication
    {
        /// <summary>
        /// Commands list
        /// </summary>
        private static Dictionary<string, CommandInfo> commands;

        /// <summary>
        /// Gets the commands.
        /// </summary>
        internal static Dictionary<string, CommandInfo> Commands
        {
            get { return commands; }
        }

        /// <summary>
        /// The Main entry point.
        /// </summary>
        /// <param name="args">The args.</param>
        public static void Main(string[] args)
        {
            InitializeCommands();

            Console.Title = "FCIS - Image Processing - Command Line";
            Console.WriteLine("Welcome to FCIS Image Processing Command Line ");

            string command;

            do
            {
                do
                {
                    Console.Write("IP> ");
                    command = Console.ReadLine();
                }
                while (string.IsNullOrEmpty(command));
            }
            while (ParseCommand(command));
        }

        /// <summary>
        /// Initializes the commands.
        /// </summary>
        private static void InitializeCommands()
        {
            commands = new Dictionary<string, CommandInfo>
                           {
                               {
                                   "exit",
                                   new CommandInfo
                                       {
                                           Description = "Exits the program", Delegate = CommandLine.Commands.Exit
                                       }
                                   },
                               {
                                   "help",
                                   new CommandInfo
                                       {
                                           Description = "Lists all the commands", Delegate = CommandLine.Commands.Help
                                       }
                                   },
                               {
                                   "hello",
                                   new CommandInfo
                                       {
                                           Description = "Give it your name it says hello", Delegate = CommandLine.Commands.Hello
                                       }
                                   },
                               {
                                   "open",
                                   new CommandInfo
                                       {
                                           Description = "Open an image file", Delegate = CommandLine.Commands.Open
                                       }
                                   },
                              {
                                  "invert",
                                  new CommandInfo
                                      {
                                          Description = "Invert the image", Delegate = CommandLine.Commands.Invert
                                      }
                                  },
                            {
                                  "display",
                                  new CommandInfo
                                      {
                                          Description = "Displays the image in Ascii Art", Delegate = CommandLine.Commands.Display
                                      }
                                  }
                           };
        }

        /// <summary>
        /// Parses the command.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <returns>true when command can be executed, false when not</returns>
        private static bool ParseCommand(string command)
        {
            string[] commandParts = command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            return ExecuteCommand(commandParts);
        }

        /// <summary>
        /// Executes the command.
        /// </summary>
        /// <param name="commandWithArguments">The command with arguments.</param>
        /// <returns>returns true on success</returns>
        private static bool ExecuteCommand(string[] commandWithArguments)
        {
            if (commands.ContainsKey(commandWithArguments[0]))
            {
                return commands[commandWithArguments[0]].Delegate(commandWithArguments);
            }

            Console.WriteLine("'{0}' is not a recognized command. try 'help' to list up all the commands with descriptions\n", commandWithArguments[0]);
            return true;
        }

        /// <summary>
        /// Command Info
        /// </summary>
        internal class CommandInfo
        {
            /// <summary>
            /// Gets or sets the description of the command
            /// </summary>
            public string Description { get; set; }

            /// <summary>
            /// Gets or sets the delegate of the command to be invoked
            /// </summary>
            public Func<string[], bool> Delegate { get; set; }
        }
    }
}
